﻿Shader "Tiny Shader/Rim"
{
	Properties
	{
		// 用于控制模型的颜色
		_MainColor("Main Color", Color) = (1, 1, 1, 1)
		// 用于控制颜色明亮度
		_Emiss("Emiss", Float) = 1.0
		// 用于控制边缘衰减对比度
		_RimPower("Rim Power", Float) = 1.0
	}

	SubShader
	{
		Tags {"Queue" = "Transparent"}

		Pass
		{
			// 开启深度写入
			ZWrite On
			// 不写入颜色值
			ColorMask 0

			CGPROGRAM

			#pragma vertex vert
			#pragma fragment frag

			float4 vert(float4 vertexPos : POSITION) : SV_POSITION
			{
				return UnityObjectToClipPos(vertexPos);
			}

			float4 frag(void) :COLOR
			{
				return half4(1.0, 1.0, 1.0, 1.0);
			}

			ENDCG
		}

		Pass
		{
			ZWrite Off
			Blend SrcAlpha One

			CGPROGRAM

			#pragma vertex vert
			#pragma fragment frag

			#include "UnityCG.cginc"

			struct appdata
			{
				float4 vertex : POSITION;
				float3 normal : NORMAL;
			};

			struct v2f
			{
				float4 pos : SV_POSITION;
				float3 normal_world : TEXCOORD1;
				float3 view_world : TEXCOORD2;
			};

			float4 _MainColor;
			float _Emiss;
			float _RimPower;

			v2f vert(appdata v)
			{
				v2f o;

				o.pos = UnityObjectToClipPos(v.vertex);
				// 将模型空间的法线方向转换到世界空间
				o.normal_world = normalize(mul(float4(v.normal, 0.0), unity_WorldToObject)).xyz;

				// 将顶点坐标由模型空间转换到世界空间
				float3 pos_world = mul(unity_ObjectToWorld, v.vertex).xyz;
				// 求出世界空间的视角方向
				o.view_world = normalize(_WorldSpaceCameraPos.xyz - pos_world);

				return o;
			}

			half4 frag(v2f i) : SV_Target
			{
				float3 normal_world = normalize(i.normal_world);
				float3 view_world = normalize(i.view_world);

				// 获取颜色，并与_Emiss相乘用于控制输出颜色的强度
				float3 col = _MainColor.xyz * _Emiss;

				float NdotV = saturate(dot(normal_world, view_world));
				// 通过_RimPower作为点乘结果的乘方因子，控制边缘透明度衰减对比度
				float fresnel = pow((1.0 - NdotV), _RimPower);
				// 同时通过_Emiss来控制透明程度
				float alpha = saturate(fresnel * _Emiss);

				// 组合RGB颜色值和透明度作为最终输出到屏幕的颜色
				return half4(col, alpha);
			}

			ENDCG
		}
	}
}